【问题标题】:BreezeSharp - ExecuteQuery fails with NullReferenceExceptionBreezeSharp - ExecuteQuery 失败并出现 NullReferenceException
【发布时间】:2014-07-04 01:58:34
【问题描述】:

我使用 BreezeJS 已经有一段时间了,我对它有很好的经验。当我开始使用 .NET 开发移动应用程序时,我决定尝试一下 BreezeSharp。

我浏览了文档和 ToDo 示例,并成功创建了 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 ...;
    }

我有从 BaseEntity 继承的客户端 PriceBook 类,它具有服务器 PriceBook 实体的子集。

控制器中的元数据方法被命中,但我无法命中 PriceBooks 方法。相反,我得到 NullReferenceException: Object reference not set to an instance of an object.

我尝试过不使用 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

解决方案: 我发现问题出在枚举属性上。 我在服务器上需要我在客户端省略的枚举属性:

[必填] 公共数据存储数据存储 { 获取;放; }

我通过将此属性添加到客户端来修复空引用问题。 现在我在解析该枚举时遇到了问题,但这是另一个问题。

【问题讨论】:

  • 没有足够的信息来提供帮助,您可能应该阅读this 的答案。假设您从 QueryPriceBooksFrom 方法看到消息框,那么我怀疑传入的 entityManager 为空。 BeginInit 中的 var entityManager = new EntityManager 是可疑的,因为它创建了一个新的局部变量。在QueryPriceBooksFrom 中设置断点应该可以清楚地表明出了什么问题,如果那是错误的来源。

标签: .net breeze breeze-sharp


【解决方案1】:

这可能是一个枚举问题。 Breeze# 0.5.5 现在支持枚举。

【讨论】:

  • Jay,问题仍然存在。如果客户端实体上不存在枚举属性,则抛出 NullReferenceException。这是属性元数据:{ "name": "DataStore", "type": "Edm.Self.DataStore", "nullable": "false" }, 我尝试在客户端省略必需的字符串属性,但它毫无例外地通过了。 { "name": "Description", "type": "Edm.String", "fixedLength": "false", "maxLength": "Max", "unicode": "true", "nullable": "false" }, 这意味着只有在客户端省略枚举属性时才会出现问题。
【解决方案2】:

感谢您试用 Breeze.sharp。

我尝试修改我们的“湿脚”示例,使其看起来更像您的代码,但我无法重现此异常。这里有几个请求:

  1. 由于元数据方法被点击并且您的服务与 Breezejs 一起使用,您应该能够通过将浏览器指向来点击 PriceBooks 方法

    http://127.0.0.1:81/api/cache/PriceBooks

您能否确认这会产生您所有 PriceBooks 的 Json 表示形式。

  1. 由于这看起来像一个客户端异常,您能否在 ExecuteQuery() 调用周围的 catch() 块中放置一个断点,检查空引用异常并将堆栈跟踪发送给我吗?如果有任何内部异常,请将它们的类型、消息和堆栈跟踪发送给我。

更新:

我们已经重现了这个问题。我们将在下一个版本中添加更多信息。

【讨论】:

  • PriceBooks 网址很好,它按预期返回了所有内容。问题在于枚举属性。有关详细信息,请参阅问题帖子(我也添加了 StackTrace)。谢谢
猜你喜欢
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
  • 2018-02-24
  • 1970-01-01
  • 2017-11-01
相关资源
最近更新 更多