从Microsoft.WindowsAzure.Storage.Table迁移到Azure.Data.Tables的反序列化问题
解决Azure.Data.Tables反序列化类型不匹配时的崩溃问题
针对迁移后遇到的反序列化异常问题,有两种实用方案可以实现“反序列化失败时将属性设为null”的需求:
方案一:手动映射TableEntity(灵活可控)
先将数据查询为原始的TableEntity类型(不会自动进行类型转换,避免崩溃),再手动将每个属性映射到自定义实体,过程中捕获转换异常并设为null。
var table = tableServiceClient.GetTableClient(CloudTableNames.Workstations); // 查询原始TableEntity,跳过自动反序列化 var tableEntities = table.Query<TableEntity>(c => c.PartitionKey == customerId); var workstations = new List<WorkstationInfoTableEntity>(); foreach (var entity in tableEntities) { var workstation = new WorkstationInfoTableEntity { PartitionKey = entity.PartitionKey, RowKey = entity.RowKey, Timestamp = entity.Timestamp, ETag = entity.ETag }; // 处理Documents属性:尝试Base64解码,失败则设为null if (entity.TryGetValue(nameof(WorkstationInfoTableEntity.Documents), out var docsValue) && docsValue is string docsStr) { try { workstation.Documents = Convert.FromBase64String(docsStr); } catch (FormatException) { workstation.Documents = null; } } // 处理DateTime?类型属性:尝试转换,空字符串或失败均设为null if (entity.TryGetValue(nameof(WorkstationInfoTableEntity.MyDocumentsLastRestoreDate), out var restoreDateValue) && restoreDateValue is string restoreDateStr) { workstation.MyDocumentsLastRestoreDate = DateTime.TryParse(restoreDateStr, out var date) ? date : null; } if (entity.TryGetValue(nameof(WorkstationInfoTableEntity.MyDocumentsModifiedOn), out var modifiedOnValue) && modifiedOnValue is string modifiedOnStr) { workstation.MyDocumentsModifiedOn = DateTime.TryParse(modifiedOnStr, out var date) ? date : null; } // 其他属性按相同逻辑处理 workstations.Add(workstation); } var results = workstations.OrderBy(c => c.Name).ToArray();
方案二:继承TableEntity并重写ReadEntity(封装性好)
让自定义实体继承TableEntity而非直接实现ITableEntity,重写ReadEntity方法来控制属性的转换逻辑,捕获异常并设置null值。
public class WorkstationInfoTableEntity : TableEntity { public byte[] Documents { get; set; } public DateTime? MyDocumentsLastRestoreDate { get; set; } public DateTime? MyDocumentsModifiedOn { get; set; } // 其他属性... public override void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext) { // 先处理PartitionKey、RowKey等基础属性 base.ReadEntity(properties, operationContext); // 处理Documents属性 if (properties.TryGetValue(nameof(Documents), out var docProp)) { try { // 优先尝试读取二进制值,若为字符串则尝试Base64解码 Documents = docProp.BinaryValue ?? Convert.FromBase64String(docProp.StringValue); } catch (FormatException) { Documents = null; } } // 处理MyDocumentsLastRestoreDate if (properties.TryGetValue(nameof(MyDocumentsLastRestoreDate), out var restoreProp)) { try { MyDocumentsLastRestoreDate = restoreProp.DateTimeOffsetValue?.DateTime; } catch (FormatException) { MyDocumentsLastRestoreDate = null; } // 单独处理空字符串场景 if (restoreProp.StringValue == string.Empty) { MyDocumentsLastRestoreDate = null; } } // 处理MyDocumentsModifiedOn if (properties.TryGetValue(nameof(MyDocumentsModifiedOn), out var modifiedProp)) { try { MyDocumentsModifiedOn = modifiedProp.DateTimeOffsetValue?.DateTime; } catch (FormatException) { MyDocumentsModifiedOn = null; } if (modifiedProp.StringValue == string.Empty) { MyDocumentsModifiedOn = null; } } // 其他属性按相同逻辑处理 } }
使用时直接查询该实体类即可,重写的ReadEntity会自动处理异常:
var table = tableServiceClient.GetTableClient(CloudTableNames.Workstations); var workstations = table.Query<WorkstationInfoTableEntity>(c => c.PartitionKey == customerId); var results = workstations.OrderBy(c => c.Name).ToArray();
内容的提问来源于stack exchange,提问作者kseeker
相关产品推荐
相关产品推荐

