BreezeSharp - выполнить ExecuteQuery с NullReferenceExeption
Я работал с BreezeJS некоторое время, и у меня был большой опыт с этим. Когда я начал разработку мобильного приложения в.NET, я решил попробовать BreezeSharp.
Я ознакомился с документацией и примером задач, а также успешно создал проект, описанный в http://www.breezejs.com/breeze-sharp-documentation/get-your-feet-wet.
У меня возникла проблема с выполнением запроса на моем существующем контроллере Web Api (который отлично работает с BreezeJS).
Вот метод запроса:
private async Task<IEnumerable<PriceBook>> QueryPriceBooksFrom(EntityManager entityManager)
{
try
{
var query = new EntityQuery<PriceBook>().From("PriceBooks");
var result = await entityManager.ExecuteQuery(query);
return result;
}
catch (Exception e)
{
MessageBox.Show(e.GetType().Name + ": " + e.Message);
return new PriceBook[0];
}
}
А вот код из BeginInit():
DataContext = this;
Configuration.Instance.ProbeAssemblies(typeof(PriceBook).Assembly);
var entityManager = new EntityManager("http://127.0.0.1:81/api/cache/");
entityManager.MetadataStore.NamingConvention = new NamingConvention().WithClientServerNamespaceMapping("clientNamespace", "serverNamespace");
entityManager.MetadataStore.AllowedMetadataMismatchTypes = MetadataMismatchType.AllAllowable;
entityManager.MetadataStore.MetadataMismatch += (s, e) =>
{
// Log the mismatch
var message = string.Format("{0} : Type = {1}, Property = {2}, Allow = {3}",
e.MetadataMismatchType, e.StructuralTypeName, e.PropertyName, e.Allow);
Console.WriteLine(message);
// Disallow missing navigation properties on the TodoItem entity type
if (e.MetadataMismatchType == MetadataMismatchType.MissingCLRNavigationProperty &&
e.StructuralTypeName.StartsWith("PriceBook"))
{
e.Allow = false;
}
};
И вот метод контроллера:
[HttpGet]
public IQueryable<PriceBook> PriceBooks(ODataQueryOptions options)
{
return ...;
}
У меня есть клиентский класс PriceBook, унаследованный от BaseEntity, который имеет подмножество серверных сущностей PriceBook.
Метод метаданных в контроллере используется, но я не могу использовать метод PriceBooks. Вместо этого я получаю NullReferenceException: ссылка на объект не установлена на экземпляр объекта.
Я пытался без параметра ODataQueryOptions и с различными версиями EntityQuery, но без успеха.
Исключение не возникает, когда я пытаюсь вызвать entityManager.fetchMetadata(), но метод метаданных снова вызывается при получении PriceBook.
У кого-нибудь есть идеи в чем может быть проблема?
Изменить: Вот StackTrace вопроса:
at Breeze.Sharp.CsdlMetadataProcessor.ParseCsdlDataProperty(StructuralType parentType, JObject csdlProperty, List`1 keyNamesOnServer) in c:\GitHub\breeze.sharp\Breeze.Sharp\CsdlMetadataProcessor.cs:line 136
at Breeze.Sharp.CsdlMetadataProcessor.<>c__DisplayClass14.<ParseCsdlEntityType>b__10(JToken csdlDataProp) in c:\GitHub\breeze.sharp\Breeze.Sharp\CsdlMetadataProcessor.cs:line 109
at Breeze.Sharp.Core.EnumerableFns.ForEach[T](IEnumerable`1 items, Action`1 action) in c:\GitHub\breeze.sharp\Breeze.Sharp\Core\EnumerableFns.cs:line 35
at Breeze.Sharp.CsdlMetadataProcessor.ParseCsdlEntityType(JObject csdlEntityType) in c:\GitHub\breeze.sharp\Breeze.Sharp\CsdlMetadataProcessor.cs:line 108
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Breeze.Sharp.CsdlMetadataProcessor.ProcessMetadata(MetadataStore metadataStore, String jsonMetadata) in c:\GitHub\breeze.sharp\Breeze.Sharp\CsdlMetadataProcessor.cs:line 33
at Breeze.Sharp.MetadataStore.<FetchMetadata>d__a.MoveNext() in c:\GitHub\breeze.sharp\Breeze.Sharp\MetadataStore.cs:line 166
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Breeze.Sharp.EntityManager.<FetchMetadata>d__3.MoveNext() in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityManager.cs:line 198
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Breeze.Sharp.EntityManager.<ExecuteQuery>d__b.MoveNext() in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityManager.cs:line 230
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Breeze.Sharp.EntityManager.<ExecuteQuery>d__6`1.MoveNext() in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityManager.cs:line 208
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at StanleySteemer.Nimbus.Mobile.MainWindow.<QueryPriceBooksFrom>d__9.MoveNext() in c:\Projects\SSI\Nimbus\source\StanleySteemer.Nimbus.Mobile\MainWindow.xaml.cs:line 109
Решение: я выяснил, что проблема была в свойстве enum. Мне требуется свойство enum на сервере, которое я пропустил на клиенте:
[Обязательно] public DataStore DataStore { get; задавать; }
Я исправил проблему с нулевой ссылкой, добавив это свойство на сторону клиента. Теперь у меня есть проблема с анализом этого перечисления, но это для другого вопроса. Спасибо за помощь.
2 ответа
Спасибо за попытку Breeze.sharp.
Я попытался изменить наш пример "мокрых ног", чтобы он больше походил на ваш код, но я не смог воспроизвести это исключение. Вот пара запросов:
Так как метод метаданных используется и ваш сервис работает с Breezejs, вы должны иметь возможность использовать метод PriceBooks, указав в браузере
http://127.0.0.1:81/api/cache/PriceBooks
Не могли бы вы подтвердить, что это дает Json представления всех ваших PriceBooks.
- Поскольку это выглядит как исключение на стороне клиента, не могли бы вы поместить точку останова в блок catch(), окружающий ваш вызов ExecuteQuery(), изучить исключение нулевой ссылки и отправить мне трассировку стека? Если есть какие-то внутренние исключения, пришлите мне их типы, сообщения и трассировки стека.
Обновить:
Мы воспроизвели эту проблему. Мы добавим более информативное сообщение в следующем выпуске.
Вероятно, это была проблема enum. Перечисления теперь поддерживаются в Breeze# 0.5.5.