#c# #asp.net #azure #azure-table-storage
#c# #asp.net #azure #azure-table-storage
Вопрос:
Я недавно обновил свой ASP.NET проект (MVC5) нацелен на Azure SDK 2.3 с библиотекой хранения 4.1, и я сталкиваюсь со странной ошибкой, когда пытаюсь сохранить что-либо в хранилище таблиц.
Ошибка:
Необработанное исключение типа ‘Microsoft.WindowsAzure.Хранение.В Microsoft произошло исключение StorageException.WindowsAzure.Storage.dll
Дополнительная информация: было указано примитивное значение; однако ожидалось значение непримитивного типа «.
Мои модели попадают в хранилище таблиц через репозитории, которые используют a 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.
Что-то изменилось внутри, что делает мой шаблон недействительным?
Комментарии:
1. У меня та же ошибка, с пустым ожидаемым типом, с использованием Web API 2 и OData V4 … нет абсолютно никакой помощи в этой ошибке, что когда-либо. Это сводит меня с ума!
Ответ №1:
Поскольку в сети нет ничего (пока) об этой ошибке, и это практически единственное место, где она обсуждается, я добавлю решение, даже если мой контекст отличается от вашего. Ошибка точно такая же, поэтому я предполагаю, что она происходит из того же места.
Для меня причиной проблемы был унаследованный первичный ключ. Первичный ключ сериализованного объекта должен быть естественным и не переопределяться. Если у класса есть свойство ID, DerivedClass также должен будет объявить свойство ID как «новое», или свойство ID должно быть перемещено из Class в DerivedClass.
Вот более подробная информация: http://jerther.blogspot.ca/2014/12/aspnet-odata-v4-primitive-value-was.html
Я действительно считаю, что это ошибка, а не ограничение, поскольку унаследованный ключ очень хорошо работает с Entity Framework и Fluent API.
Я надеюсь, что это поможет и сэкономит время.
Комментарии:
1. Это случилось со мной, когда я использовал fluent API для сопоставления поля с тем же именем, что и у другого поля. В обеих наших ситуациях я считаю, что эта ошибка вызвана двумя полями, сопоставленными с одним и тем же именем.
Ответ №2:
В конце я решил обновить весь код репозитория, чтобы отказаться от устаревшего 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);
}
}