Azure存储客户端v4.1—期望非原语类型的值
本文关键字:原语 类型 期望 存储 客户端 v4 Azure | 更新日期: 2023-09-27 18:10:22
我最近升级了我的ASP。. NET项目(MVC5)的目标Azure SDK 2.3与存储库4.1和遇到一个奇怪的错误,当我试图保存任何东西到表存储。
错误:类型为"Microsoft.WindowsAzure.Storage"的未处理异常。在Microsoft.WindowsAzure.Storage.dll
附加信息:指定了原始值;但是,非基本类型的值是必需的。
我的模型通过存储库进入表存储,存储库使用TableServiceContext
进行添加、更新、删除和保存。
我的模型遵循以下模式:
[System.Data.Services.Common.DataServiceKey(new string[] { "PartitionKey", "RowKey" })]
public class PersistedAlert : Alert, ITableEntity
{
public string PartitionKey
{
get { return this.StudentId; }
set { this.StudentId = value; }
}
public string RowKey
{
get { return this.Id; }
set { this.Id = value; }
}
public DateTime Timestamp { get; set; }
public new int Type { get; set; } //hides Enum type in Alert base class
}
在升级过程中,我需要替换掉所有对
的引用System.Data.Services。*
Microsoft.Data.Services。*
…除了OData库之外。
是否内部发生了一些变化,使我的模式不再有效?
既然没有什么(尚未)对这个错误在网上,这是几乎唯一的地方讨论,我将添加一个解决方案,即使我的上下文是不同于你的。错误是完全相同的,所以我猜它来自同一个地方。
对我来说,是继承的主键导致了这个问题。序列化实体的主键必须是自然的,不能被覆盖。如果Class有一个ID属性,那么DerivedClass也必须将ID属性声明为"new",或者将ID属性从Class移到DerivedClass。
这里有更多的细节:http://jerther.blogspot.ca/2014/12/aspnet-odata-v4-primitive-value-was.html
我相信这是一个bug,而不是一个限制,因为继承的键在实体框架和Fluent API中工作得很好。
最后,我决定升级所有的存储库代码,以摆脱基于WCF的已弃用的TableServiceContext
,而是通过CloudTable
进行调用。我只能假设上面提到的某个库的内部发生了变化,导致了我所看到的问题。
除了更改存储库代码之外,我还需要更新实体以继承Azure ITableEntity
(我以前有自己的风格),如下所示:
public class PersistedAlert : Alert, Microsoft.WindowsAzure.Storage.Table.ITableEntity
{
public string PartitionKey
{
get { return this.StudentId; }
set { this.StudentId = value; }
}
public string RowKey
{
get { return this.Id; }
set { this.Id = value; }
}
public DateTimeOffset Timestamp { get; set; }
public string ETag { get; set; }
public void ReadEntity(IDictionary<string, Microsoft.WindowsAzure.Storage.Table.EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
Microsoft.WindowsAzure.Storage.Table.TableEntity.ReadUserObject(this, properties, operationContext);
}
public IDictionary<string, Microsoft.WindowsAzure.Storage.Table.EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
return Microsoft.WindowsAzure.Storage.Table.TableEntity.WriteUserObject(this, operationContext);
}
}